using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using UnityEngine;

namespace Gj.Network.IpRouting
{
    /// <summary>
    /// IP路由管理器，负责管理多个IP地址并自动选择最佳路径
    /// </summary>
    public class IpRouter
    {
        private static IpRouter _instance;
        public static IpRouter Instance => _instance ??= new IpRouter();

        /// <summary>
        /// IP地址信息
        /// </summary>
        [System.Serializable]
        public class IpInfo
        {
            public string ip;
            public int port;
            public float latency; // 延迟（毫秒）
            public bool isAvailable;
            public DateTime lastChecked;
            public int failureCount;
            public int maxFailures = 3;

            public IpInfo(string ip, int port = 80)
            {
                this.ip = ip;
                this.port = port;
                this.latency = float.MaxValue;
                this.isAvailable = true;
                this.lastChecked = DateTime.MinValue;
                this.failureCount = 0;
            }

            /// <summary>
            /// 获取用于HTTP请求的IP地址（不包含协议）
            /// </summary>
            public string GetRequestIp()
            {
                return $"{ip}:{port}";
            }
        }

        private List<IpInfo> _ipList = new List<IpInfo>();
        private IpInfo _currentBestIp;
        private readonly object _lockObject = new object();
        private bool _isCheckingLatency = false;

        /// <summary>
        /// 添加IP地址到路由列表
        /// </summary>
        public void AddIp(string ip, int port = 80)
        {
            lock (_lockObject)
            {
                var existingIp = _ipList.FirstOrDefault(x => x.ip == ip && x.port == port);
                if (existingIp == null)
                {
                    _ipList.Add(new IpInfo(ip, port));
                    UnityEngine.Debug.Log($"[IpRouter] Added IP: {ip}:{port}");
                }
            }
        }

        /// <summary>
        /// 批量添加IP地址
        /// </summary>
        public void AddIpList(List<IpInfo> ipList)
        {
            lock (_lockObject)
            {
                foreach (var ipInfo in ipList)
                {
                    var existingIp = _ipList.FirstOrDefault(x => x.ip == ipInfo.ip && x.port == ipInfo.port);
                    if (existingIp == null)
                    {
                        _ipList.Add(ipInfo);
                        UnityEngine.Debug.Log($"[IpRouter] Added IP: {ipInfo.GetRequestIp()}");
                    }
                }
            }
        }

        /// <summary>
        /// 移除IP地址
        /// </summary>
        public void RemoveIp(string ip, int port = 80)
        {
            lock (_lockObject)
            {
                var ipToRemove = _ipList.FirstOrDefault(x => x.ip == ip && x.port == port);
                if (ipToRemove != null)
                {
                    _ipList.Remove(ipToRemove);
                    UnityEngine.Debug.Log($"[IpRouter] Removed IP: {ip}:{port}");

                    // 如果移除的是当前最佳IP，重新选择
                    if (_currentBestIp == ipToRemove)
                    {
                        _currentBestIp = null;
                    }
                }
            }
        }

        /// <summary>
        /// 获取当前最佳IP地址
        /// </summary>
        public IpInfo GetBestIp()
        {
            lock (_lockObject)
            {
                if (_currentBestIp != null && _currentBestIp.isAvailable)
                {
                    return _currentBestIp;
                }

                // 选择最佳IP
                var availableIps = _ipList.Where(x => x.isAvailable).ToList();
                if (availableIps.Count == 0)
                {
                    UnityEngine.Debug.LogWarning("[IpRouter] No available IP addresses!");
                    return null;
                }

                _currentBestIp = availableIps.OrderBy(x => x.latency).First();
                UnityEngine.Debug.Log($"[IpRouter] Selected best IP: {_currentBestIp.GetRequestIp()} (latency: {_currentBestIp.latency}ms)");
                return _currentBestIp;
            }
        }

        /// <summary>
        /// 检查所有IP的延迟
        /// </summary>
        public async Task CheckAllLatencyAsync()
        {
            if (_isCheckingLatency) return;

            _isCheckingLatency = true;
            UnityEngine.Debug.Log("[IpRouter] Starting latency check for all IPs...");

            var tasks = new List<Task>();
            lock (_lockObject)
            {
                foreach (var ipInfo in _ipList)
                {
                    tasks.Add(CheckLatencyAsync(ipInfo));
                }
            }

            await Task.WhenAll(tasks);
            _isCheckingLatency = false;

            // 重新选择最佳IP
            GetBestIp();
            UnityEngine.Debug.Log("[IpRouter] Latency check completed.");
        }

        /// <summary>
        /// 检查单个IP的延迟
        /// </summary>
        private async Task CheckLatencyAsync(IpInfo ipInfo)
        {
            try
            {
                var stopwatch = Stopwatch.StartNew();

                // 使用Ping检查网络连通性
                using (var ping = new System.Net.NetworkInformation.Ping())
                {
                    var reply = await Task.Run(() => ping.Send(ipInfo.ip, 5000)); // 5秒超时

                    if (reply.Status == IPStatus.Success)
                    {
                        ipInfo.latency = reply.RoundtripTime;
                        ipInfo.isAvailable = true;
                        ipInfo.failureCount = 0;
                        ipInfo.lastChecked = DateTime.Now;
                        UnityEngine.Debug.Log($"[IpRouter] {ipInfo.GetRequestIp()} - Latency: {ipInfo.latency}ms");
                    }
                    else
                    {
                        ipInfo.isAvailable = false;
                        ipInfo.failureCount++;
                        UnityEngine.Debug.LogWarning($"[IpRouter] {ipInfo.GetRequestIp()} - Ping failed: {reply.Status}");
                    }
                }
            }
            catch (Exception ex)
            {
                ipInfo.isAvailable = false;
                ipInfo.failureCount++;
                UnityEngine.Debug.LogError($"[IpRouter] Error checking {ipInfo.GetRequestIp()}: {ex.Message}");
            }
        }

        /// <summary>
        /// 标记IP为失败
        /// </summary>
        public void MarkIpFailed(string ip, int port = 80)
        {
            lock (_lockObject)
            {
                var ipInfo = _ipList.FirstOrDefault(x => x.ip == ip && x.port == port);
                if (ipInfo != null)
                {
                    ipInfo.failureCount++;
                    if (ipInfo.failureCount >= ipInfo.maxFailures)
                    {
                        ipInfo.isAvailable = false;
                        UnityEngine.Debug.LogWarning($"[IpRouter] IP {ipInfo.GetRequestIp()} marked as unavailable due to failures");

                        // 如果失败的是当前最佳IP，重新选择
                        if (_currentBestIp == ipInfo)
                        {
                            _currentBestIp = null;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 重置IP状态
        /// </summary>
        public void ResetIpStatus(string ip, int port = 80)
        {
            lock (_lockObject)
            {
                var ipInfo = _ipList.FirstOrDefault(x => x.ip == ip && x.port == port);
                if (ipInfo != null)
                {
                    ipInfo.failureCount = 0;
                    ipInfo.isAvailable = true;
                    UnityEngine.Debug.Log($"[IpRouter] Reset status for IP: {ipInfo.GetRequestIp()}");
                }
            }
        }

        /// <summary>
        /// 获取所有IP状态信息
        /// </summary>
        public List<IpInfo> GetAllIpStatus()
        {
            lock (_lockObject)
            {
                return new List<IpInfo>(_ipList);
            }
        }

        /// <summary>
        /// 清空所有IP
        /// </summary>
        public void ClearAllIps()
        {
            lock (_lockObject)
            {
                _ipList.Clear();
                _currentBestIp = null;
                UnityEngine.Debug.Log("[IpRouter] Cleared all IP addresses");
            }
        }
    }
}

